package com.bsj.travel.device.service.impl;

import cn.hutool.core.io.file.FileReader;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bsj.travel.def.common.DO.CategoryDO;
import com.bsj.travel.def.common.DO.ProductCategoryDO;
import com.bsj.travel.def.common.DTO.web.category.CategoryDTO;
import com.bsj.travel.def.common.DTO.web.category.CategorySearchDTO;
import com.bsj.travel.def.common.VO.CategoryVO;
import com.bsj.travel.def.global.JsonResult;
import com.bsj.travel.def.global.JsonResultEnum;
import com.bsj.travel.device.service.CategoryService;
import com.bsj.travel.exception.ApiException;
import com.bsj.travel.mapper.mysql.CategoryMapper;
import com.bsj.travel.mapper.mysql.ProductCategoryMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/***
 * @description CategoryServiceImpl
 * @author LiJiaXin
 * @version 1.0.0
 * @time 2024/1/22 14:47
 **/
@Service
public class CategoryServiceImpl implements CategoryService {

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private ProductCategoryMapper productCategoryMapper;

    /**
     * 添加品类
     *
     * @param categoryDTO
     * @return com.bsj.travel.def.global.JsonResult
     * @author ljx
     * @time 2024/1/22 14:50
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult addCategory(CategoryDTO categoryDTO) {
        paramCheck(categoryDTO);
        CategoryDO categoryDO = new CategoryDO();
        BeanUtils.copyProperties(categoryDTO, categoryDO);
        categoryDO.setContent(contentRead(categoryDTO.getContent()));
        if (categoryMapper.insert(categoryDO) > 0) {
            return JsonResult.success();
        } else {
            return JsonResult.fail();
        }
    }

    /**
     * 删除品类
     *
     * @param categoryId
     * @return com.bsj.travel.def.global.JsonResult
     * @author ljx
     * @time 2024/1/22 14:51
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult deleteCategory(Long categoryId) {
        if (categoryId == null) {
            return JsonResult.fail(JsonResultEnum.PARAM_ERROR);
        }
        if (categoryMapper.selectById(categoryId) == null) {
            return JsonResult.fail(JsonResultEnum.CATEGORY_IS_NOT_EXIST);
        }
        List<ProductCategoryDO> dos = productCategoryMapper.selectList(new QueryWrapper<>(ProductCategoryDO.class)
                .eq("categoryId", categoryId));
        if (dos.size() > 0) {
            return JsonResult.fail("品类下存在产品，请先删除产品");
        }
        if (categoryMapper.deleteById(categoryId) > 0) {
            return JsonResult.success();
        } else {
            return JsonResult.fail();
        }
    }

    /**
     * 修改品类
     *
     * @param categoryDTO
     * @return com.bsj.travel.def.global.JsonResult
     * @author ljx
     * @time 2024/1/22 14:51
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public JsonResult updateCategory(CategoryDTO categoryDTO) {
        Long categoryId = categoryDTO.getCategoryId();
        if (categoryId == null) {
            return JsonResult.fail(JsonResultEnum.PARAM_ERROR);
        }
        if (categoryMapper.selectById(categoryId) == null) {
            return JsonResult.success(JsonResultEnum.CATEGORY_IS_NOT_EXIST);
        }
        paramCheck(categoryDTO);
        CategoryDO categoryDO = new CategoryDO();
        BeanUtils.copyProperties(categoryDTO, categoryDO);
        categoryDO.setContent(contentRead(categoryDTO.getContent()));
        if (categoryMapper.updateById(categoryDO) > 0) {
            return JsonResult.success();
        } else {
            return JsonResult.fail();
        }
    }

    /**
     * 根据品类id获取品类信息
     *
     * @param categoryId
     * @return com.bsj.travel.def.common.VO.CategoryVO
     * @author ljx
     * @time 2024/1/22 14:51
     */
    @Override
    public CategoryVO getCategoryInfoById(Long categoryId) {
        if (categoryId == null) {
            throw new ApiException(JsonResultEnum.PARAM_ERROR);
        }
        CategoryDO categoryDO = categoryMapper.selectById(categoryId);
        if (categoryDO == null) {
            throw new ApiException(JsonResultEnum.CATEGORY_IS_NOT_EXIST);
        }
        CategoryVO categoryVO = new CategoryVO();
        BeanUtils.copyProperties(categoryDO, categoryVO);
        return categoryVO;
    }

    /**
     * 品类分页
     *
     * @param categorySearchDTO
     * @return com.bsj.travel.def.global.JsonResult<java.util.List < com.bsj.travel.def.common.VO.CategoryVO>>
     * @author ljx
     * @time 2024/1/22 14:52
     */
    @Override
    public JsonResult<List<CategoryVO>> pageCategory(CategorySearchDTO categorySearchDTO) {
        IPage<CategoryDO> page = new Page<>(categorySearchDTO.getPageNumber(), categorySearchDTO.getPageSize());
        QueryWrapper<CategoryDO> queryWrapper = new QueryWrapper<>();
        String categoryName = categorySearchDTO.getCategoryName();
        Integer usageScenario = categorySearchDTO.getUsageScenario();
        if (StringUtils.isNotBlank(categoryName)) {
            queryWrapper.eq("categoryName", categoryName);
        }
        if (usageScenario != null) {
            queryWrapper.eq("usageScenario", usageScenario);
        }
        List<CategoryVO> categoryVOS = new LinkedList<>();
        IPage<CategoryDO> iPage = categoryMapper.selectPage(page, queryWrapper);
        int total = (int) iPage.getTotal();
        if (total == 0) {
            return JsonResult.success(categoryVOS, total);
        }
        categoryVOS = iPage.getRecords().stream().map(categoryDO -> {
            CategoryVO categoryVO = new CategoryVO();
            BeanUtils.copyProperties(categoryDO, categoryVO);
            return categoryVO;
        }).collect(Collectors.toList());
        return JsonResult.success(categoryVOS, total);
    }

    /**
     * 内容读取
     *
     * @param content
     * @return java.lang.String
     * @author ljx
     * @time 2024/1/25 10:56
     */
    private String contentRead(MultipartFile content) {
        String result = null;
        try {
            File file = File.createTempFile("temp", null);
            content.transferTo(file);
            FileReader fileReader = new FileReader(file);
            result = fileReader.readString();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (StringUtils.isBlank(result)) {
            throw new ApiException(JsonResultEnum.CONTENT_IS_NULL);
        }
        return result;
    }

    /**
     * 参数校验
     *
     * @param categoryDTO
     * @return void
     * @author ljx
     * @time 2024/1/25 10:45
     */
    private void paramCheck(CategoryDTO categoryDTO) {
        MultipartFile file = categoryDTO.getContent();
        Long categoryId = categoryDTO.getCategoryId();
        if (file == null || file.getSize() <= 0) {
            throw new ApiException(JsonResultEnum.FILE_IS_NULL);
        }
        if (file.getSize() > 1000) {
            throw new ApiException(JsonResultEnum.FAIL, "文件内容长度需要限制在1000以内");
        }
        String originalFilename = file.getOriginalFilename();
        if (!originalFilename.contains("txt")) {
            throw new ApiException(JsonResultEnum.FAIL, "文件必须是包含json内容的txt文档");
        }
        QueryWrapper<CategoryDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("categoryName", categoryDTO.getCategoryName());
        if (categoryId != null) {
            queryWrapper.ne("categoryId", categoryId);
        }
        CategoryDO categoryDO = categoryMapper.selectOne(queryWrapper);
        if (categoryDO != null) {
            throw new ApiException(JsonResultEnum.CATEGORY_NAME_IS_EXIST);
        }
    }

}
